package com.ease.util {
	import com.ease.util.logging.LogManager;
	
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.geom.Matrix;
	import flash.net.URLRequest;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	
	import mx.containers.accordionClasses.AccordionHeader;
	import mx.controls.tabBarClasses.Tab;
	import mx.core.BitmapAsset;
	import mx.core.UIComponent;
	import mx.logging.ILogger;
	import mx.logging.LogEventLevel;

	/**
	 * Provides a workaround for using run-time loaded graphics in styles and properties which require a Class reference
	 */
	public class IconUtil extends BitmapAsset {

		private static var dictionary:Dictionary;

      private static var imageMap:Dictionary;
      
      private static var _logger:ILogger = LogManager.getLogger(IconUtil);

		/**
		 * Used to associate run-time graphics with a target
		 * @param target A reference to the component associated with this icon
		 * @param source A url to a JPG, PNG or GIF file you wish to be loaded and displayed
		 * @param width Defines the width of the graphic when displayed
		 * @param height Defines the height of the graphic when displayed
		 * @return A reference to the IconUtility class which may be treated as a BitmapAsset
		 * @example &lt;mx:Button id="button" icon="{IconUtility.getClass(button, 'http://www.yourdomain.com/images/test.jpg')}" /&gt;
		 */
		public static function getClass( target:Object, source:String, width:Number = 16, height:Number = 16 ):Class {
			if(!dictionary) {
				dictionary = new Dictionary(true);
            imageMap = new Dictionary(true);
			}
         
			var loader:Loader = null;
         if (!imageMap[source]) {
            loader = new Loader();
   			loader.load(new URLRequest(source as String), new LoaderContext(true));
            loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorListener);
            imageMap[source] = {loader:loader, bitmap:undefined, width:width, height:height};
         }
			dictionary[target] = { source:source};
			return IconUtil;
		}
      
      public static function removeClass(target:Object):void {
         if (dictionary[target]) {
            delete dictionary[target];
         }
      }

		/**
		 * @private
		 */
		public function IconUtil():void {
			addEventListener(Event.ADDED, addedHandler)
		}

		private function addedHandler(event:Event):void {
			if(parent) {
            if (dictionary[parent]) {
               getData(parent);
            }
            else if (parent.hasOwnProperty("data")) {
               var item:Object = parent["data"];
               getData(item);
            }
			}
		}

		private function getData(object:Object):void {
         var data:* = dictionary[object];
         if (data) {
            var sourceData:* = data.source;
            var bitData:* = imageMap[sourceData]
            if (bitData) {
               if (bitData.bitmap) {
                  bitmapData = bitData.bitmap;
                  return;
               }
               else {
                  bitmapData = new BitmapData(bitData.width, bitData.height, true, 0);
                  bitData.bitmap = bitmapData;
               }
               var loader:Loader = bitData.loader as Loader;
               if(loader) {
                  if(!loader.content) {
                     loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
                  } else {
                     displayLoader(loader);
                  }
               }
            }
         }
		}

		private function displayLoader( loader:Loader ):void {
			if(!bitmapData) {
				bitmapData = new BitmapData(loader.content.width, loader.content.height, true, 0);
			}
			bitmapData.draw(loader, new Matrix(bitmapData.width/loader.width, 0, 0, bitmapData.height/loader.height, 0, 0));
         if (loader.hasEventListener(Event.COMPLETE)) {
            loader.removeEventListener(Event.COMPLETE, completeHandler);
         }
			if(parent is UIComponent) {
				var component:UIComponent = parent as UIComponent;
				component.invalidateSize();
            removeEventListener(Event.ADDED, addedHandler);
			}
		}

		private function completeHandler(event:Event):void {
			if(event && event.target && event.target is LoaderInfo) {
				displayLoader(event.target.loader as Loader);
			}
		}

      private static function ioErrorListener(event:IOErrorEvent):void {
         _logger.log(LogEventLevel.WARN, event.text);
      }
	}
}